//
//  ZS2.h
//  Part of Z-Way.C library
//
//  Created by Poltorak Serguei on 03/05/17.
//
//  Copyright (c) 2017 Z-Wave.Me
//  All rights reserved
//  info@z-wave.me
//
//  This source file is subject to the terms and conditions of the
//  Z-Wave.Me Software License Agreement which restricts the manner
//  in which it may be used.
//

#ifndef _ZS2_H_
#define _ZS2_H_

#include "z-s2.h"

#define SECURITY_Sx_NETWORK_KEY_LENGTH	16
#define SECURITY_S2_PRIVATE_KEY_LENGTH	32
#define SECURITY_S2_PUBLIC_KEY_LENGTH	SECURITY_S2_PRIVATE_KEY_LENGTH
#define SECURITY_S2_DSK_LENGTH  16

typedef struct __KeyPair_s
{
    ZWBYTE private[SECURITY_S2_PRIVATE_KEY_LENGTH];
    ZWBYTE public[SECURITY_S2_PUBLIC_KEY_LENGTH];
} __KeyPair_t;

// Exported functions to libS2
ZWEXPORT uint8_t S2_send_frame(struct S2* ctxt, const s2_connection_t* peer, uint8_t* buf, uint16_t len);
ZWEXPORT uint8_t S2_send_frame_no_cb(struct S2* ctxt, const s2_connection_t* peer, uint8_t* buf, uint16_t len);
ZWEXPORT uint8_t S2_send_frame_multi(struct S2* ctxt, s2_connection_t* peer, uint8_t* buf, uint16_t len);
ZWEXPORT void S2_resync_event(struct S2 * s2_ctx, node_t r_node);
ZWEXPORT void S2_resynchronization_event(struct S2* ctxt, node_t remote_node, sos_event_reason_t reason, uint8_t seqno, node_t local_node);
ZWEXPORT void S2_send_done_event(struct S2 * ctxt, s2_tx_status_t status);
ZWEXPORT void S2_set_timeout(struct S2* ctx, uint32_t interval);
ZWEXPORT void S2_stop_timeout(struct S2* ctx);
ZWEXPORT uint8_t s2_inclusion_set_timeout(struct S2* ctx, uint32_t interval);
ZWEXPORT void s2_inclusion_stop_timeout(struct S2* ctxt);
ZWEXPORT uint8_t S2_get_commands_supported(struct S2* ctxt, uint8_t class_id, uint8_t* cmdClasses, uint8_t length);
ZWEXPORT void S2_msg_received_event(struct S2* ctxt, s2_connection_t* src, uint8_t* data, uint16_t len);
ZWEXPORT void keystore_private_key_read(struct S2* s2_ctx, uint8_t *priv_key);
ZWEXPORT void keystore_secondary_private_key_read(struct S2* s2_ctx, uint8_t *pub_key);
ZWEXPORT bool keystore_network_key_read(struct S2* s2_ctx, uint8_t keyclass, uint8_t *buf);
ZWEXPORT bool keystore_network_key_write(struct S2* s2_ctx, uint8_t keyclass, const uint8_t *keybuf);
ZWEXPORT bool keystore_network_key_clear(struct S2* s2_ctx, uint8_t keyclass);

// Forward declarations
void zs2_event_handler(struct S2* s2_ctx, zwave_event_t* ev);
char *_zs2_key_class_name(ZWBYTE keyclass);
char *_zs2_key_class_network_key_dh_path(ZWBYTE keyclass);
char *_zs2_key_class_granted_key_dh_path(ZWBYTE keyclass);
char *_zs2_key_class_nif_dh_path(ZWBYTE keyclass);
ZWError _zs2_timer_remove(ZWay zway, ZDeviceS2 s2);
ZWError _zs2_inclusion_timer_remove(ZWay zway, ZDeviceS2 s2);
void _zs2_delayed_controller_interview_timer_start(ZWay zway);
void _zs2_s2_interview_timeout_stop(ZWay zway);
void _zs2_s2_interview_timeout_timer_start(ZWay zway);
ZWError _zs2_delayed_controller_interview_timer_remove(ZWay zway);
ZWBYTE _zs2_class_id_to_key_class(ZWBYTE class_id);
ZWBYTE _zs2_key_class_to_class_id(ZWBYTE key_class);
void _zs2_inclusion_abort(ZWay zway, ZDeviceS2 s2);
ZWError _zs2_inclusion_joining_start(ZWay zway);
ZWError _zs2_key_pair_regenerate_and_load(ZWay zway);
ZWError _zs2_key_pair_regenerate(const ZWay zway, __KeyPair_t *const key_pair);
ZWError _zs2_key_pair_load(const ZWay zway, const __KeyPair_t *const key_pair);

ZWBYTE _zway_controller_highest_key_granted(ZWay zway);
ZWBYTE _zway_device_highest_key_granted(ZWay zway, ZDevice device);
ZWBOOL _zway_device_is_security_key_granted(ZWay zway, ZDevice device, ZWBYTE securityKey);
void _zway_s2_detach_job(ZWay zway, ZJob job);

// Forward declaration from SecurityS2 implementation
ZWBOOL filter_waiting_security_s2(const ZJob job);
ZWError _zway_controller_security_s2_post_init(ZWay zway);
ZWError _zway_cc_security_s2_send_data(ZWay zway, ZDevice device, ZWNODE node_id, ZWBYTE scheme, ZWBYTE length, const ZWBYTE *data);
ZWError __SecurityS2GetSecureNIFs(ZWay zway, ZCommand command);
ZWError __SecurityS2Failed(ZWay zway, ZCommand command);
ZWError __SecurityS2SkipInterview(ZWay zway, ZCommand command);
ZWBOOL __SecurityS2CheckInterviewDone(ZWay zway, ZCommand commandS0, ZCommand commandS2, ZWBOOL versionSet);
ZWCSTR __SecurityS2CommandDescription(ZWBYTE command, ZWBOOL *encap);
ZWCSTR __SecurityS2KEXFailDescription(ZWBYTE reason);
ZWError __SecurityS2Parse(ZWay zway, ZCommand command, const ZWBYTE *data, ZWBYTE length, ZWBYTE keyClass, ZWNODE dst_node_id);
ZW_CC_CMD_TYPE __SecurityS2CommandType(ZWay zway, ZWBYTE command);

// Forward declaration from Security implementation
ZWError __SecurityGetSecureNIF(ZWay zway, ZCommand command);
ZWError __SecuritySetNetworkKey(ZWay zway, const ZWBYTE *key, ZWBYTE length);

#endif
